﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Navigation;
using System.Windows.Shapes;
using HelixToolkit.Wpf;
using System.Xml.Linq;
using netDxf;
using netDxf.Entities;
using CPlatePrintSys.Annotation.Converters;
using CPlatePrintSys.Annotation.ViewModels;
using CPlatePrintSys.Annotation.Models;
using CPlatePrintSys.Annotation.Controls;
using CPlatePrintSys.Annotation.Events;
using CPlatePrintSys.Domain.Events;
using CPlatePrintSys.Domain.Models;
using Prism.Events;
using Prism.Navigation.Regions;

namespace CPlatePrintSys.Annotation.Views
{
    /// <summary>
    /// DxfAnnotation.xaml 的交互逻辑
    /// </summary>
    public partial class DxfAnnotationView : UserControl
    {
        private readonly IEventAggregator _eventAggregator;

        public DxfAnnotationView()
        {
            InitializeComponent();
            this.Loaded += DxfAnnotationView_Loaded;
            

            // _eventAggregator = ServiceLocator.Current.GetInstance<IEventAggregator>();

            // 修正后的代码：
            _eventAggregator = (IEventAggregator)Prism.Ioc.ContainerLocator.Container.Resolve(typeof(IEventAggregator));

            // 订阅布局模式改变事件
            SubscribeToLayoutModeEvents();
        }

        private void DxfAnnotationView_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.DataContext is DxfAnnotationViewModel vm &&
                this.annotationDisplayer != null)
            {
                vm.ControlId = this.annotationDisplayer.ControlId;
                vm.MirrorControlId = this.annotationDisplayerMirror.ControlId;
                
                // 设置默认的活动控件为normal控件
                vm.SetActiveControl(this.annotationDisplayer.ControlId);
            }

            // 订阅镜像同步事件
            SubscribeToMirrorSyncEvents();
        }

        /// <summary>
        /// 处理AnnotationDisplayerControl的鼠标点击事件
        /// 当鼠标点击控件时，设置该控件为活动控件
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">鼠标事件参数</param>
        private void AnnotationDisplayer_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (sender is AnnotationDisplayerControl control && 
                this.DataContext is DxfAnnotationViewModel vm)
            {
                // 设置当前控件为活动控件
                vm.SetActiveControl(control.ControlId);
                
                // 通知控件它现在是活动控件
                control.SetAsActiveControl();
                
                // 直接设置控件的编辑模式，确保状态同步
                EditingMode currentMode = EditingMode.None;
                if (vm.IsEditMode)
                    currentMode = EditingMode.Editing;
                else if (vm.IsInAddMode)
                    currentMode = EditingMode.Adding;
                else if (vm.IsInDeletingMode)
                    currentMode = EditingMode.Deleting;
                
                control.ForceSetEditingMode(currentMode);
                
                // 不阻止事件继续传播，让控件内部能正常处理鼠标事件
                // e.Handled = false; // 默认不阻止
            }
        }

        /// <summary>
        /// 订阅镜像同步事件
        /// </summary>
        private void SubscribeToMirrorSyncEvents()
        {
            try
            {
                // 订阅镜像同步事件
                _eventAggregator.GetEvent<MirrorSyncEvent>().Subscribe(OnMirrorSyncEvent, ThreadOption.UIThread);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"订阅镜像同步事件失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 处理镜像同步事件
        /// </summary>
        /// <param name="args">镜像同步事件参数</param>
        private void OnMirrorSyncEvent(MirrorSyncEventArgs args)
        {
            try
            {
                // 关键修复：让normal控件也能处理自己的镜像同步事件
                // 这样normal控件就能调用SyncAddEntity来创建自己的映射
                
                // 根据目标控件ID找到对应的控件
                AnnotationDisplayerControl targetControl = null;
                if (args.TargetControlId == "normal")
                {
                    targetControl = this.annotationDisplayer;
                }
                else if (args.TargetControlId == "mirror")
                {
                    targetControl = this.annotationDisplayerMirror;
                }

                if (targetControl != null)
                {
                    // 直接调用控件的公共镜像同步方法
                    targetControl.OnMirrorSync(args);
                }
                
                // 关键修复：只在Add操作时让源控件也处理事件
                // 这样normal控件在发布Add事件后，也能调用SyncAddEntity来创建自己的映射
                // 对于Edit、Move、Rotate等操作，不需要源控件重复处理，避免映射关系混乱
                if (args.SourceControlId != args.TargetControlId && args.Operation == MirrorSyncOperation.Add)
                {
                    AnnotationDisplayerControl sourceControl = null;
                    if (args.SourceControlId == "normal")
                    {
                        sourceControl = this.annotationDisplayer;
                    }
                    else if (args.SourceControlId == "mirror")
                    {
                        sourceControl = this.annotationDisplayerMirror;
                    }
                    
                    if (sourceControl != null)
                    {
                        System.Diagnostics.Debug.WriteLine($"源控件 {args.SourceControlId} 处理Add事件，创建自己的映射");
                        sourceControl.OnMirrorSync(args);
                    }
                }
                else if (args.SourceControlId != args.TargetControlId && args.Operation != MirrorSyncOperation.Add)
                {
                    System.Diagnostics.Debug.WriteLine($"跳过源控件处理 {args.Operation} 事件，避免映射关系混乱");
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"处理镜像同步事件失败: {ex.Message}");
            }
        }

        private void annotationDisplayer_MouseMove(object sender, MouseEventArgs e)
        {

        }

        public void HelixViewport_MouseMoveMirror(object sender, MouseEventArgs e)
        {
            // 获取鼠标在 HelixViewport3D 中的屏幕坐标
            System.Windows.Point mousePosition = e.GetPosition(sender as HelixViewport3D);

            // 将屏幕坐标转换为 3D 空间中的点
            var viewport = (sender as HelixViewport3D).Viewport;
            var ray = Viewport3DHelper.Point2DtoRay3D(viewport, mousePosition);

            if (ray != null)
            {
                // 定义平面（例如 Z = 0 的 XY 平面）
                Point3D planePoint = new Point3D(0, 0, 0);
                Vector3D planeNormal = new Vector3D(0, 0, 1);

                // 计算射线与平面的交点
                var intersection = IntersectRayWithPlane(ray, planePoint, planeNormal);

                if (intersection.HasValue)
                {
                    // 显示平面上的 3D 坐标
                    var worldPoint = intersection.Value;
                    //mousePositionTextMirror.Text = $"X: {worldPoint.X:F2}, Y: {worldPoint.Y:F2}, Z: {worldPoint.Z:F2}";
                }
                else
                {
                    //mousePositionTextMirror.Text = "无法计算 3D 坐标";
                }
            }
            else
            {
                //mousePositionTextMirror.Text = "无法生成射线";
            }
        }



        public void HelixViewport_MouseMoveNormal(object sender, MouseEventArgs e)
        {
            // 获取鼠标在 HelixViewport3D 中的屏幕坐标
            System.Windows.Point mousePosition = e.GetPosition(sender as HelixViewport3D);

            // 将屏幕坐标转换为 3D 空间中的点
            var viewport = (sender as HelixViewport3D).Viewport;
            var ray = Viewport3DHelper.Point2DtoRay3D(viewport, mousePosition);

            if (ray != null)
            {
                // 定义平面（例如 Z = 0 的 XY 平面）
                Point3D planePoint = new Point3D(0, 0, 0);
                Vector3D planeNormal = new Vector3D(0, 0, 1);

                // 计算射线与平面的交点
                var intersection = IntersectRayWithPlane(ray, planePoint, planeNormal);

                if (intersection.HasValue)
                {
                    // 显示平面上的 3D 坐标
                    var worldPoint = intersection.Value;
                    mousePositionTextNormal.Text = $"X: {worldPoint.X:F2}, Y: {worldPoint.Y:F2}, Z: {worldPoint.Z:F2}";
                }
                else
                {
                    mousePositionTextNormal.Text = "无法计算 3D 坐标";
                }
            }
            else
            {
                mousePositionTextNormal.Text = "无法生成射线";
            }
        }

        private Point3D? IntersectRayWithPlane(Ray3D ray, Point3D planePoint, Vector3D planeNormal)
        {
            // 计算平面法向量与射线方向的点积
            double denominator = Vector3D.DotProduct(planeNormal, ray.Direction);

            // 如果点积为 0，射线与平面平行，无交点
            if (Math.Abs(denominator) < 1e-6)
            {
                return null;
            }

            // 计算射线起点到平面点的向量
            Vector3D originToPlane = planePoint - ray.Origin;

            // 计算参数 t
            double t = Vector3D.DotProduct(originToPlane, planeNormal) / denominator;

            // 如果 t < 0，交点在射线的反方向，无效
            if (t < 0)
            {
                return null;
            }

            // 计算交点
            Point3D intersection = ray.Origin + t * ray.Direction;
            return intersection;
        }

        /// <summary>
        /// 订阅布局模式改变事件
        /// </summary>
        private void SubscribeToLayoutModeEvents()
        {
            if (_eventAggregator != null)
            {
                _eventAggregator.GetEvent<LayoutModeChangedEvent>().Subscribe(OnLayoutModeChanged, ThreadOption.UIThread);
            }
        }

        /// <summary>
        /// 处理布局模式改变事件
        /// </summary>
        /// <param name="layoutMode">新的布局模式</param>
        private void OnLayoutModeChanged(LayoutMode layoutMode)
        {
            switch (layoutMode)
            {
                case LayoutMode.MirrorLayout:
                    // 镜像布局模式：显示normal和mirror两个控件
                    ShowMirrorLayout();
                    break;
                case LayoutMode.MergedLayout:
                    // 合并布局模式：只显示normal控件，占据全部区域
                    ShowMergedLayout();
                    break;
            }
        }

        /// <summary>
        /// 显示镜像布局（normal上镜像下）
        /// </summary>
        private void ShowMirrorLayout()
        {
            // 显示分割行和镜像行
            splitterRow.Height = new GridLength(10);
            mirrorRow.Height = new GridLength(1, GridUnitType.Star);
            
            // 显示镜像控件和分割器
            gridSplitter.Visibility = Visibility.Visible;
            annotationDisplayerMirror.Visibility = Visibility.Visible;
            mousePositionTextMirror.Visibility = Visibility.Collapsed;
            
            // 设置normal控件占据上半部分
            annotationDisplayer.SetValue(Grid.RowProperty, 0);
        }

        /// <summary>
        /// 显示合并布局（normal控件占据全部区域）
        /// </summary>
        private void ShowMergedLayout()
        {
            // 隐藏分割行和镜像行
            splitterRow.Height = new GridLength(0);
            mirrorRow.Height = new GridLength(0);
            
            // 隐藏镜像控件和分割器
            gridSplitter.Visibility = Visibility.Collapsed;
            annotationDisplayerMirror.Visibility = Visibility.Collapsed;
            mousePositionTextMirror.Visibility = Visibility.Collapsed;
            
            // 设置normal控件占据全部区域
            annotationDisplayer.SetValue(Grid.RowProperty, 0);
            annotationDisplayer.SetValue(Grid.RowSpanProperty, 3);
        }
    }
}
